package com.snap.awesomeserial.logger;

import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.support.annotation.NonNull;
import android.support.annotation.Nullable;

import com.orhanobut.logger.LogStrategy;
import com.snap.awesomeserial.utils.FileUtils;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;

/**
 * msg中含有"exp begin"为开始
 * 含有"exp end"为结束
 * 记录一个文件
 */
public class ExpLogStrategy implements LogStrategy {

    @NonNull
    private final Handler handler;

    ExpLogStrategy(@NonNull Handler handler) {
        this.handler = Utils.checkNotNull(handler);
    }

    @Override
    public void log(int level, @Nullable String tag, @NonNull String message) {
        Utils.checkNotNull(message);
        handler.sendMessage(handler.obtainMessage(level, message));
    }

    static class WriteHandler extends Handler {

        private final String folder;
        private File logFile;
        private OutputStreamWriter fileWriter;

        WriteHandler(@NonNull Looper looper, @NonNull String folder) {
            super(Utils.checkNotNull(looper));
            this.folder = Utils.checkNotNull(folder);
        }

        @Override
        public void handleMessage(@NonNull Message msg) {
            String content = (String) msg.obj;
            if (content.contains("exp begin")) {
                beginLog(content);
            } else if (content.contains("exp end")) {
                endLog(content);
            } else {
                log(content);
            }
        }

        private void beginLog(String content) {
            closeWriter();
            logFile = getLogFile(folder, "log");
            try {
                FileOutputStream fos = new FileOutputStream(logFile, true);
                fileWriter = new OutputStreamWriter(fos, StandardCharsets.UTF_8);
            } catch (IOException e) {
                e.printStackTrace();
            }
            log(content);
        }

        private void log(String content) {
            if (fileWriter == null) return;
            try {
                fileWriter.append(content);
                fileWriter.flush();
            } catch (IOException e) {
            }
        }

        private void endLog(String content) {
            log(content);
            closeWriter();
        }

        private void closeWriter() {
            if (fileWriter != null) {
                try {
                    fileWriter.close();
                } catch (IOException e) {
                    if (fileWriter != null) {
                        try {
                            fileWriter.flush();
                            fileWriter.close();
                        } catch (IOException e1) { /* fail silently */ }
                    }
                } finally {
                    fileWriter = null;
                }
            }
            if (logFile != null) {
                FileUtils.ensureWriteFile(logFile);
                logFile = null;
            }
        }

        private File getLogFile(@NonNull String folderName, @NonNull String fileName) {
            Utils.checkNotNull(folderName);
            Utils.checkNotNull(fileName);

            File folder = new File(folderName);
            if (!folder.exists()) {
                folder.mkdirs();
            }

            return new File(folder, String.format("%s.txt", fileName));
        }
    }
}
